package com.uzhie.jt808.msg.entity;

import com.uzhie.jt808.JT808MsgBody;
import com.uzhie.jt808.msg.entity.JT_200.*;
import com.uzhie.jt808.util.DateUtil;
import com.uzhie.jt808.util.StringUtil;
import org.apache.log4j.Logger;

import java.util.*;

/**
 * 位置信息汇报
 */
public class JT_0200 implements JT808MsgBody {


    private static Logger logger = Logger.getLogger(JT_0200.class);
    /**
     * 报警标志
     */

    private int alarmFlag;

    public final int getAlarmFlag() {
        return alarmFlag;
    }

    public final void setAlarmFlag(int value) {
        alarmFlag = value;
    }

    /**
     * 状态
     */

    private int status;

    public final int getStatus() {
        return status;
    }

    public final void setStatus(int value) {
        status = value;
    }

    /**
     * 纬度,以度为单位的纬度值乘以10的6次方，精确到百万分之一度
     */

    private int latitude;

    public final int getLatitude() {
        return latitude;
    }

    public final void setLatitude(int value) {
        latitude = value;
    }

    /**
     * 经度,以度为单位的经度值乘以10的6次方，精确到百万 分之一度
     */

    private int longitude;

    public final int getLongitude() {
        return longitude;
    }

    public final void setLongitude(int value) {
        longitude = value;
    }

    /**
     * 海拔高度，单位为米（m）
     */

    private short altitude;

    public final short getAltitude() {
        return altitude;
    }

    public final void setAltitude(short value) {
        altitude = value;
    }

    /**
     * 速度,1/10km/h
     */

    // ORIGINAL LINE: private ushort speed;
    private short speed;

    // ORIGINAL LINE: public ushort getSpeed()
    public final short getSpeed() {
        return speed;
    }

    // ORIGINAL LINE: public void setSpeed(ushort value)
    public final void setSpeed(short value) {
        speed = value;
    }

    /**
     * 方向,0～359，正北为0，顺时针
     */

    // ORIGINAL LINE: private ushort course;
    private short course;

    // ORIGINAL LINE: public ushort getCourse()
    public final short getCourse() {
        return course;
    }

    // ORIGINAL LINE: public void setCourse(ushort value)
    public final void setCourse(short value) {
        course = value;
    }

    /**
     * 时间,YY-MM-DD-hh-mm-ss（GMT+8时间，本标准中之后涉及的时间均采用此时区）
     */
    private String time;

    public final String getTime() {
        return time;
    }

    /**
     * 当前位置信息是否属于视频报警
     *
     * @return
     */
    public final int isMediaWarning() {
        IPositionAdditionalItem additionalItem = null;

        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x014) {
                additionalItem = item;
                break;
            }

        }

        if (additionalItem != null) {
            Media_Warn mileage = (Media_Warn) additionalItem;
            return mileage.getType();
        } else {
            return 0;
        }
    }

    /**
     * 判断位置信息是否包含苏标报警信息
     *
     * @return true 是 false 不是
     */
    public final boolean isJSWarning() {
        boolean result = false;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item instanceof JS_SuperWarn) {
                result = true;
                break;
            }
        }
        return result;
    }

    public final void setTime(String value) {
        time = value;
    }

    private boolean valid;

    public final boolean isValid() {
        return valid;
    }

    public final void setIsValid(boolean value) {
        valid = value;
    }

    private String strStatus;

    public final String getStrStatus() {
        return strStatus;
    }

    public final void setStrStatus(String value) {
        strStatus = value;
    }

    private String strWarn;

    public final String getStrWarn() {
        return strWarn;
    }

    public final void setStrWarn(String value) {
        strWarn = value;
    }


    /**
     * 获取异常告警类型及疲劳度
     *
     * @return
     */
    public Media_Fatigue getMediaFatigue() {
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x018) {
                return (Media_Fatigue) item;
            }

        }
        return null;
    }

    /**
     * 获取视频告警类别
     *
     * @return
     */
    public Media_Warn getMediaWarn() {
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x014) {
                return (Media_Warn) item;
            }

        }
        return null;
    }

    /**
     * 获取通信信号强弱
     *
     * @return
     */
    public final int getIgnal() {
        IPositionAdditionalItem addtionalItem = null;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x30) {
                addtionalItem = item;
                break;
            }

        }
        if (addtionalItem != null) {
            PostitionAdditional_IgnalIntensity mileage = (PostitionAdditional_IgnalIntensity) addtionalItem;
            return mileage.getIntensity();
        } else {
            return 0;
        }
    }

    /**
     * 获取Gps信号强弱
     *
     * @return
     */
    public final int getGps() {
        IPositionAdditionalItem addtionalItem = null;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x31) {
                addtionalItem = item;
                break;
            }

        }
        if (addtionalItem != null) {
            PostitionAdditional_GpsIntensity mileage = (PostitionAdditional_GpsIntensity) addtionalItem;
            return mileage.getIntensity();
        } else {
            return 0;
        }
    }

    /**
     * 里程
     */
    public final int getMileage() {
        IPositionAdditionalItem addtionalItem = null;

        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x01) {
                addtionalItem = item;
                break;
            }

        }

        if (addtionalItem != null) {
            PostitionAdditional_Mileage mileage = (PostitionAdditional_Mileage) addtionalItem;
            return mileage.getMileage();
        } else {
            return 0;
        }
    }

    /**
     * 油量
     */

    // ORIGINAL LINE: public ushort getOil()
    public final short getOil() {

        IPositionAdditionalItem addtionalItem = null;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x02) {
                addtionalItem = item;
                break;
            }

        }
        if (addtionalItem != null) {
            PostitionAdditional_Oil oil = (PostitionAdditional_Oil) addtionalItem;
            return oil.getOil();
        } else {
            return 0;
        }
    }

    /**
     * 获取车辆信号位
     *
     * @return
     */
    public final int getExpandVehicleSignals() {
        IPositionAdditionalItem addtionalItem = null;
        for (Iterator iterator = getAdditionals().iterator(); iterator.hasNext(); ) {
            IPositionAdditionalItem item = (IPositionAdditionalItem) iterator.next();
            if (item.getAdditionalId() == 0x025) {
                addtionalItem = item;
                break;
            }
        }

        if (addtionalItem != null) {
            PostitionAdditional_ExpandVehicleSignals ExpandVehicleSignals = (PostitionAdditional_ExpandVehicleSignals) addtionalItem;
            return ExpandVehicleSignals.getExpandVehicleSignals();
        } else {
            return 0;
        }
    }

    /**
     * 进出区域报警附加信息
     */
    public final PostitionAdditional_InOutAreaAlarmAdditional getInOutAreaAlarmAdditional() {

        IPositionAdditionalItem addtionalItem = null;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x12) {
                addtionalItem = item;
                break;
            }

        }
        if (addtionalItem != null) {
            PostitionAdditional_InOutAreaAlarmAdditional additional = (PostitionAdditional_InOutAreaAlarmAdditional) addtionalItem;
            return additional;
        }
        return null;
    }

    /**
     * 电压
     */

    // ORIGINAL LINE: public ushort getVoltage()
    public final short getVoltage() {

        IPositionAdditionalItem addtionalItem = null;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0xE1) {
                addtionalItem = item;
                break;
            }

        }
        if (addtionalItem != null) {
            PostitionAdditional_Voltage voltage = (PostitionAdditional_Voltage) addtionalItem;
            return voltage.getVoltage();
        } else {
            return 0;
        }
    }

    /**
     * 记录仪速度
     */

    // ORIGINAL LINE: public ushort getRecorderSpeed()
    public final short getRecorderSpeed() {
        IPositionAdditionalItem addtionalItem = null;
        for (IPositionAdditionalItem item : getAdditionals()) {
            if (item.getAdditionalId() == 0x03) {
                addtionalItem = item;
                break;
            }

        }
        if (addtionalItem != null) {
            PostitionAdditional_RecorderSpeed recorrderSpeed = (PostitionAdditional_RecorderSpeed) addtionalItem;
            return recorrderSpeed.getRecorderSpeed();
        } else {
            return 0;
        }
    }

    // 位置附加信息项列表
    private java.util.ArrayList<IPositionAdditionalItem> additionals;

    protected java.util.ArrayList<IPositionAdditionalItem> getAdditionals() {
        return additionals;
    }

    private void setAdditionals(
            java.util.ArrayList<IPositionAdditionalItem> value) {
        additionals = value;
    }

    public final byte[] WriteToBytes() {

        MyBuffer buff = new MyBuffer();

        buff.put(getAlarmFlag());
        buff.put(getStatus());
        buff.put(getLatitude());
        buff.put(getLongitude());
        buff.put(getAltitude());
        buff.put(getSpeed());
        buff.put(getCourse());
        buff.put(Byte.parseByte(getTime().substring(2, 4), 16));
        buff.put(Byte.parseByte(getTime().substring(5, 7), 16));
        buff.put(Byte.parseByte(getTime().substring(8, 10), 16));
        buff.put(Byte.parseByte(getTime().substring(11, 13), 16));
        buff.put(Byte.parseByte(getTime().substring(14, 16), 16));
        buff.put(Byte.parseByte(getTime().substring(17, 19), 16));
        if (getAdditionals() != null && getAdditionals().size() > 0) {
            for (IPositionAdditionalItem ad : getAdditionals()) {
                buff.put(ad.getAdditionalId());
                buff.put(ad.getAdditionalLength());
                buff.put(ad.WriteToBytes());
            }
        }

        return buff.array();
    }

    public final void ReadFromBytes(byte[] bytes) {
        MyBuffer buff = new MyBuffer(bytes);
        setAlarmFlag(buff.getInt());
        setStatus(buff.getInt());
        setLatitude(buff.getInt());
        setLongitude(buff.getInt());
        setAltitude(buff.getShort());
        setSpeed(buff.getShort());
        setCourse(buff.getShort());
        byte[] timeBytes = buff.gets(6);
        StringBuilder builder = new StringBuilder("20");
        setTime(builder.append(String.format("%02X", timeBytes[0])).append("-")
                .append(String.format("%02X", timeBytes[1])).append("-")
                .append(String.format("%02X", timeBytes[2])).append(" ")
                .append(String.format("%02X", timeBytes[3])).append(":")
                .append(String.format("%02X", timeBytes[4])).append(":")
                .append(String.format("%02X", timeBytes[5])).toString());
        setAdditionals(new java.util.ArrayList<>());
        while (buff.hasRemain()) {
            byte additionalId = buff.get();
            byte additionalLength = buff.get();
            byte[] additionalBytes = buff.gets(additionalLength);
            IPositionAdditionalItem item = PositionAdditionalFactory
                    .CreatePositionalFactory(additionalId, additionalLength,
                            additionalBytes);
            if (item != null) {
                getAdditionals().add(item);
            } else {
                logger.error("未知的附加协议:" + additionalId + ",附加长度:" + additionalLength);
            }
        }
        this.strWarn = Integer.toBinaryString(this.getAlarmFlag());
        strWarn = StringUtil.leftPad(strWarn, 32, '0');
        this.strStatus = Integer.toBinaryString(this.getStatus());
        strStatus = StringUtil.leftPad(strStatus, 32, '0');
        setIsValid(getStrStatus().substring(30, 31).equals("1"));
    }

    @Override
    public String toString() {
        StringBuilder sBuilder = new StringBuilder();
        sBuilder.append(String.format(
                "报警标示：%1$s,状态：%2$s,经度：%3$s,纬度：%4$s,高度：%5$s,速度：%6$s,时间：%7$s",
                getAlarmFlag(), getStatus(), getLongitude(), getLatitude(),
                getAltitude(), getSpeed(), getTime()));
        return sBuilder.toString();
    }

    public final static JT_0200 createInstance() {
        JT_0200 order = new JT_0200();
        order.setAlarmFlag(0);
        order.setAltitude((short) 200);
        order.setStatus(0);
        order.setSpeed((short) 120);
        order.setLatitude(34800803);
        order.setLongitude(113608647);
        order.setCourse((short) 23);
        order.setTime(DateUtil.dateToString(new Date()));
        ArrayList<IPositionAdditionalItem> list = new java.util.ArrayList<IPositionAdditionalItem>();
        PostitionAdditional_IgnalIntensity ignale = new PostitionAdditional_IgnalIntensity();
        ignale.setIntensity(4);
        PostitionAdditional_GpsIntensity gps = new PostitionAdditional_GpsIntensity();
        gps.setIntensity(4);
        Media_Warn warn = new Media_Warn();
        warn.setType(1);
        Map<Integer, Integer> status = new HashMap<>();
        status.put(1, 1);
        warn.setStatus(status);
        Media_Dropout drop = new Media_Dropout();
        drop.setChannel(1);
        Map<Integer, Integer> status1 = new HashMap<>();
        status1.put(1, 1);
        drop.setStatus(status);

        list.add(ignale);
        list.add(gps);
        list.add(warn);
        list.add(drop);
        order.setAdditionals(list);
        return order;
    }
}